Beliebige XML-Datei in interne Tabelle einlesen

Viele Daten werden im XML-Format ausgetauscht. Um die Daten in SAP verarbeiten zu können, muss man parsen oder eine entsprechende Transformation “programmieren”. Mit XML tue ich mich manchmal etwas schwer und bin daher froh über jede Vereinfachung.

Mithilfe eines kleinen generischen Programms ist es einfach möglich, die folgende XML-Datei in eine interne Tabelle zu laden:

<?xml version="1.0" encoding="UTF-8"?>
<hierarchie1>
<hierarchie2>Beispiel XML</hierarchie2>
<hierarchie2>Tricktresor</hierarchie2>
<hierarchie2>Enno Wulff</hierarchie2>
</hierarchie1>
Interne Tabelle mit XML-Daten
Screenshot aus dem Debugger

Man sieht deutlich, dass die einzelnen Tags der XML-Datei sequentiell in die Tabelle übernommen wurden. Für viele Anwendungsfälle dürfte das für die weitere Verarbeitung ausreichen.

[notice type=’info’]Dieses Programm erzeugt lediglich die Transformation von der XML-Struktur in eine interne Tabelle. Es erfolgt keine Ausgabe![/notice]

Coding

REPORT.
TYPES tyt_tab_xml TYPE TABLE OF smum_xmltb.

DATA: gv_xml_xstring  TYPE          xstring,
      gt_xml_tab      TYPE TABLE OF smum_xmltb,
      gv_filename     TYPE          localfile,
      go_xml_document TYPE REF TO   cl_xml_document,
      gv_subrc        TYPE          sy-subrc,
      gv_size         TYPE          sy-tabix.


START-OF-SELECTION.

  PERFORM display_popup CHANGING gv_filename.

  PERFORM upload_xml USING gv_filename
                     CHANGING go_xml_document
                              gv_subrc.
  IF gv_subrc = 0.

    PERFORM parse_to_xstring USING go_xml_document
                             CHANGING gv_xml_xstring
                                      gv_size
                                      gv_subrc.
    IF gv_subrc = 0.
      PERFORM parse_xml_to_itab USING gv_xml_xstring
                                CHANGING gt_xml_tab.

    ELSE.
      EXIT.
    ENDIF.
  ELSE.
    EXIT.
  ENDIF.

END-OF-SELECTION.

FORM display_popup CHANGING cv_filename TYPE localfile.

  DATA: lt_filetable TYPE filetable,
        lv_anz_dat   TYPE i.

  cl_gui_frontend_services=>file_open_dialog(
    EXPORTING
      window_title            =     'Wählen Sie eine XML.Datei aus'    " Titel des Datei-Öffnen Dialogs
      default_filename        =     'C:\test.xml'
      initial_directory       =     'C:\' " Ausgangsverzeichnis
  CHANGING
      file_table              = lt_filetable   " Tabelle, die selektierte Dateien enthält
      rc                      = lv_anz_dat     " Rückgabewert: Anzahl Dateien oder -1 falls Fehler auftritt
  EXCEPTIONS
    OTHERS                  = 5
    ).

  READ TABLE lt_filetable INTO cv_filename INDEX 1.

ENDFORM.

FORM upload_xml USING iv_filename        TYPE localfile
                CHANGING co_xml_document TYPE REF TO cl_xml_document
                         cv_subrc        TYPE sy-subrc.
*== create the object
  CREATE OBJECT co_xml_document.

*== Upload xml file
  co_xml_document->import_from_file(
  EXPORTING
    filename = iv_filename
    RECEIVING
    retcode = cv_subrc  ).

ENDFORM.

FORM parse_to_xstring USING io_xml_document  TYPE REF TO cl_xml_document
                      CHANGING cv_xml_string TYPE xstring
                               cv_size       TYPE sy-tabix
                               cv_subrc      TYPE sy-subrc.
*== Convert to xstring
  CALL METHOD io_xml_document->render_2_xstring
    IMPORTING
      retcode = cv_subrc      " Returncode
      stream  = cv_xml_string " XString (STREAM)
      size    = cv_size.      " Anzahl Zeichen
ENDFORM.

FORM parse_xml_to_itab USING iv_xml_string TYPE xstring
                       CHANGING ct_xml_tab TYPE tyt_tab_xml.

  DATA: lt_return TYPE TABLE OF bapiret2.

*== Convert XML to itab
  CALL FUNCTION 'SMUM_XML_PARSE'
    EXPORTING
      xml_input = iv_xml_string
    TABLES
      xml_table = ct_xml_tab
      return    = lt_return.
  BREAK-POINT.

ENDFORM.

Übertragen der generischen in eine interne Tabelle

In unserem Beispiel muss die interne Tabelle das Feld “HIERARCHIE2” besitzen. Die Zuweisung aller XML-Werte der “Hierarchiestufe 2” werden dann dem Feld “ITAB-HIERARCHIE2” zugewiesen.

[notice type=’info’]Der Aufruf der Routine muss noch hinzugefügt werden. Die zu übergebene interne Tabelle kann jeden beliebigen Typ haben. In diesem Beispiel wird der Typ TYT_ITAB verwendet.[/notice]

FORM build_itab USING it_xml_tab     TYPE tyt_tab_xml
             CHANGING itab TYPE tyt_itab.

  FIELD-SYMBOLS: <ls_data_tab> LIKE LINE OF itab,
                 <ls_xml_tab>  LIKE LINE OF it_xml_tab,
                 <lv_value>    TYPE         data.

  LOOP AT it_xml_tab ASSIGNING <ls_xml_tab> WHERE hier EQ 2.
    TRANSLATE <ls_xml_tab>-cname TO UPPER CASE.
    IF <ls_xml_tab>-cname = 'HIERARCHIE2'.
      APPEND INITIAL LINE TO itab ASSIGNING <ls_data_tab>.
    ENDIF.
    ASSIGN COMPONENT <ls_xml_tab>-cname OF STRUCTURE <ls_data_tab> TO <lv_value>.
    <lv_value> = <ls_xml_tab>-cvalue.
  ENDLOOP.
ENDFORM..
Enno Wulff

COMMENTS

  • <cite class="fn">sapcurious</cite>

    Hallo,

    It’s been a long time since i didn’t practise german.
    Then, i may have misunderstood something in your thread.
    I can’t figure out what should be the type “tyt_itab” ?
    Can you describe it please ?

    Thanks

  • <cite class="fn">wolfgang</cite>

    Hallo Enno,
    danke für deinen Blog. Hat mir schon oft geholfen.
    XML ist für mich neu daher komme ich nicht so richtig weiter.
    Ich habe eine XML mit deinem Code ins SAP geladen. Nun möchte ich bestimmte Werte ändern und dann die interne Tabelle wieder als XML speichern. Gibt es da eine andere Möglichkeit als eine Transformation?
    Danke
    Gruß
    Wolfgang

Comments are closed.